<?php
namespace app\data_magic\controller;

use cmf\controller\AdminBaseController;
use app\data_magic\logic\Interpreter;
use app\data_magic\logic\Action;
use app\data_magic\widget\ListWidget;
use app\data_magic\widget\FormWidget;
use app\data_magic\widget\FilterWidget;
use app\data_magic\widget\TabsWidget;
use app\data_magic\logic\Field;
use think\Db;
use app\data_magic\struct\Result;
use app\data_magic\struct\Input;
use tree\Tree;
use app\data_magic\struct\Location;
use app\data_magic\struct\File;


class DataAdminController extends AdminBaseController
{
    public function _empty($name)
    {
        if(!preg_match("/([a-z0-9]+)-([0-9]+)/",$name,$matches)){
            $this->error("操作名称格式错误");
        }
        if($matches[1]==="action"){
            $action_id=$matches[2];
            $interpreter=new Interpreter();
            $user_id=cmf_get_current_user_id();
            $interpreter->access($user_id,["admin"]);
            $result=$interpreter->loadAction($action_id);
            if(!$result){
                $this->error($interpreter->getError());
            }
            $input=$this->loadInputParams($result,input());
            $result=$interpreter->dispath($result,$input);
            if($result->status===false){
                $message = $result->message ? $result->message : "操作失败" ;
                $this->error($message);
            }
            elseif($result->is_page===false){
                $message = $result->message ? $result->message : "操作成功" ;
                $result->redirect_params["action_id"]=$result->bindAction["id"];
                $this->success($message,url("open",$result->redirect_params));
            }
            else{
                return $this->renderPage($input,$result);
            }
        }
        else{
            $this->error("未定义的操作类型");
        }
    }
    public function open()
    {
        $action_id=input("action_id");
        $interpreter=new Interpreter();
        $user_id=cmf_get_current_user_id();
        $interpreter->access($user_id,["admin"]);
        $result=$interpreter->loadAction($action_id);
        if(!$result){
            $this->error($interpreter->getError());
        }
        $input=$this->loadInputParams($result,input());
        $result=$interpreter->dispath($result,$input);
        if($result->status===false){
            $message = $result->message ? $result->message : "操作失败" ;
            $this->error($message);
        }
        elseif($result->is_page===false){
            $message = $result->message ? $result->message : "操作成功" ;
            $result->redirect_params["action_id"]=$result->bindAction["id"];
            $this->success($message,url("open",$result->redirect_params));
        }
        else{
            return $this->renderPage($input,$result);
        }
    }
    public function tree()
    {
        $action_id="17";//input("action_id");
        $interpreter=new Interpreter();
        $user_id=cmf_get_current_user_id();
        $interpreter->access($user_id,["admin"]);
        $result=$interpreter->loadAction($action_id);
        if(!$result){
            $this->error($interpreter->getError());
        }
        $input=$this->loadInputParams($result,input());
        $result=$interpreter->dispath($result,$input);
        if($result->status===false){
            $message = $result->message ? $result->message : "操作失败" ;
            $this->error($message);
        }
        elseif($result->is_page===false){
            $message = $result->message ? $result->message : "操作成功" ;
            $result->redirect_params["action_id"]=$result->bindAction["id"];
            $this->success($message,url("open",$result->redirect_params));
        }
        else{
            return $this->renderPage2($input,$result);
        }
    }
    public function tree2()
    {
        $interpreter=new Interpreter();
        $user_id=cmf_get_current_user_id();
        $interpreter->access($user_id,["admin"]);
        $result=$interpreter->loadScene("2");
        if(!$result){
            $this->error($interpreter->getError());
        }

        return $this->fetchTreeTableWidget($result);
    }
    /**
     * @param Result $result
     */
    public function fetchTreeTableWidget($result)
    {
        $objResult = Db::table($result->table->name)->select();
        $arrResult = $objResult ? $objResult->toArray() : [];

        $tree       = new Tree();
        // $tree->icon = ['&nbsp;&nbsp;&nbsp;│ ', '&nbsp;&nbsp;&nbsp;├─ ', '&nbsp;&nbsp;&nbsp;└─ '];
        // $tree->nbsp = '&nbsp;&nbsp;&nbsp;';

        $array = [];
        foreach ($arrResult as $r) {
            $r['parent_id_node'] = ($r['parent_id']) ? ' class="child-of-node-' . $r['parent_id'] . '"' : '';
            $r['style']          = empty($r['parent_id']) ? '' : 'display:none;';

            $hrefs=[];
            foreach($result->linkActions as $link){
                if($link["data_type"]==="single"){
                    if($link["target_type"]==="exec"){
                        $message = $link["describe"] ? $link["describe"] : '确认操作？' ;
                        $url=url('open',['action_id'=>$link['id'],'data_id'=>$r['id']]);
                        $hrefs[]="<a href='$url' class='js-ajax-dialog-btn' data-msg='$message'>".$link["title"]."</a>";
                    }
                    else{
                        $url=url('open',['action_id'=>$link['id'],'data_id'=>$r['id']]);
                        $hrefs[]="<a href='$url'>".$link["title"]."</a>";
                    }
                }
            }
            $r['str_manage'] = implode("\r\n",$hrefs);
            $array[]         = $r;
        }

        $fields=[];
        foreach($result->fields as $field){
            $fields[]="<td>\$".$field->name."</td>";
        }
        $tree->init($array);
        $str = "<tr id='node-\$id' \$parent_id_node style='\$style'>
            <td>\$spacer</td>
            ".implode("\r\n",$fields)."
            <td>\$str_manage</td>
        </tr>";

        $categories = $tree->getTree(0, $str);
        $this->assign("categories",$categories);
        $this->assign("fields",$result->fields);
        return $this->fetch("tree");
    }
    public function selectRefer()
    {
        $interpreter=new Interpreter();
        $user_id=cmf_get_current_user_id();
        $result=$interpreter->access($user_id,["admin"])->loadAction(input("action_id"));
        if(!$result){
            $this->error($interpreter->getError());
        }
        $input=$this->loadInputParams($result,input());
        $result=$interpreter->dispath($result,$input);
        if($result->status===false){
            $message = $result->message ? $result->message : "操作失败" ;
            $this->error($message);
        }
        if($result->is_page===false){
            $this->error("设置错误");
        }
        foreach($result->widgets as $struct){
            if($struct instanceof ListWidget){
                $data_list=Db::table($result->table->name)->where($result->getWhere())->paginate(10);
                $this->assign('paginate', $data_list->render());
                $struct->data_list=$data_list;
                $this->assign($struct->toArray());
                $this->assign("list_widget",$this->fetch("list"));
            }
        }
        $this->assign("selected_ids",input("ids"));
        return $this->fetch("refer");
    }
    /**
     * 加载输入参数
     * @param Result $result 结果对象
     * @param string[] $input 输入值
     * @return Input
     */
    public function loadInputParams($result,$input)
    {
        $action_input=new Input();
        if(isset($input["data_id"]) && $input["data_id"]){
            $action_input->pks=$input["data_id"];
            unset($input["data_id"]);
        }
        elseif(isset($input["data_ids"])){
            $pks=$input["data_ids"];
            if(is_array($pks)){
                $action_input->pks=implode(",",$pks);
            }
            elseif(is_string($pks)){
                $action_input->pks=$pks;
            }
            unset($input["data_ids"]);
        }
        if(isset($input["filter"]) && is_array($input["filter"])){
            $action_input->where=$input["filter"];
            unset($input["filter"]);
        }

        $widget=new FormWidget();
        $action_input->data= $widget->convertInputData($result->fields,$input);
        return $action_input;
    }
    /**
     * 渲染页面
     * @param Input $input
     * @param Result $result
     */
    public function renderPage($input,$result)
    {
        foreach($result->widgets as $struct){
            if($struct instanceof TabsWidget){
                $this->assign($struct->toArray());
                $this->assign("tabs_widget",$this->fetch("tabs"));
            }
            elseif($struct instanceof FilterWidget){
                $this->assign($struct->toArray());
                $this->assign("filter_widget",$this->fetch("filters"));
            }
            elseif($struct instanceof ListWidget){
                $data_list=Db::table($result->table->name)->where($result->getWhere())->paginate(10);
                $this->assign('paginate', $data_list->render());
                $struct->data_list=$data_list;
                $this->assign($struct->toArray());
                $this->assign("list_widget",$this->fetch("list"));
            }
            elseif($struct instanceof FormWidget){
                $data_type=$result->action->data_type;
                $action_type=$result->action->action_type;
                if($data_type==="single"){
                    // $struct->data_item=$action->find();
                }
                if($action_type==="update"){
                    if($data_type==="single") $struct->hidden["data_id"]=$input->pks;
                    elseif($data_type==="multi") $struct->hidden["data_ids"]=$input->pks;
                    else{
                        $list=$action->select();
                        $pks=[];
                        foreach($list as $item){
                            $pks[]=$item[$action->scene->primary_key];
                        }
                        $pks=implode(",",$pks);
                        $hidden["data_ids"]=$pks;
                    }
                }
                $this->assign($struct->toArray());
                $this->assign("form_widget",$this->fetch("form"));
            }
        }
        return $this->fetch("page");
    }
    /**
     * 渲染页面
     * @param Input $input
     * @param Result $result
     */
    public function renderPage2($input,$result)
    {
        foreach($result->widgets as $struct){
            if($struct instanceof TabsWidget){
                $this->assign($struct->toArray());
                $this->assign("tabs_widget",$this->fetch("tabs"));
            }
            elseif($struct instanceof FilterWidget){
                $this->assign($struct->toArray());
                $this->assign("filter_widget",$this->fetch("filters"));
            }
            elseif($struct instanceof ListWidget){
                $this->assign("list_widget",$this->fetchTreeTableWidget($result));
            }
            elseif($struct instanceof FormWidget){
                $data_type=$result->action->data_type;
                $action_type=$result->action->action_type;
                if($data_type==="single"){
                    // $struct->data_item=$action->find();
                }
                if($action_type==="update"){
                    if($data_type==="single") $struct->hidden["data_id"]=$input->pks;
                    elseif($data_type==="multi") $struct->hidden["data_ids"]=$input->pks;
                    else{
                        $list=$action->select();
                        $pks=[];
                        foreach($list as $item){
                            $pks[]=$item[$action->scene->primary_key];
                        }
                        $pks=implode(",",$pks);
                        $hidden["data_ids"]=$pks;
                    }
                }
                $this->assign($struct->toArray());
                $this->assign("form_widget",$this->fetch("form"));
            }
        }
        return $this->fetch("page");
    }
}
